package com.itheima.health.service.impl;

import com.itheima.health.common.MessageConst;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrderSettingDao;
import com.itheima.health.entity.OrderSubmitParam;
import com.itheima.health.exception.CustomizeException;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.pojo.Setmeal;
import com.itheima.health.service.OrderService;
import com.itheima.health.utils.ZkLockUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.RetryNTimes;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@DubboService
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private ZkLockUtil zkLockUtil;

    @Transactional //开启事务
    @Override
    public Integer add(OrderSubmitParam orderSubmitParam) {
        /*
         * @Date: 5:48 下午 2021/1/10
         * @param: [orderSubmitParam]
         * @return: void
         * @Description: 添加预约信息
         * 1、根据名字和身份证去member表去查是否有用户
         * 2、查询OrderSetting表判断当天是否有预约信息
         * 3、查询OrderSetting判断当天预约人数是否已满
         * 4、根据手机号，订单日期和套餐id查询当前用户是否已经预约过
         * 5、
         */

        String phone = orderSubmitParam.getTelephone();
        Date date = orderSubmitParam.getOrderDate();

        //获取当天可预约人数和已经预约人数
        OrderSetting orderSetting = new OrderSetting();
        orderSetting.setOrderDate(date);
        OrderSetting selectOrderSetting = orderSettingDao.selectOne(orderSetting);
        log.info("[预约设置-add-可预约人数和已经预约人数] - selectOneMember: {}",selectOrderSetting);
        //三元判断当前数据为null返回0，否则返回原数据
        Integer number = selectOrderSetting.getNumber()==null?-1:selectOrderSetting.getNumber();
        Integer reservations = selectOrderSetting.getReservations()==null?0:selectOrderSetting.getReservations();
        //判断用户所选日期是否提前进行预约设置
        if (selectOrderSetting==null || number == -1){
            throw new CustomizeException(MessageConst.SELECTED_DATE_CANNOT_ORDER);
        }
        //判断用户预约的时间人数是否已经约满
        if (number<=reservations){
            throw new CustomizeException(MessageConst.ORDER_FULL);
        }

        Example memberExample = new Example(Member.class);
        Example.Criteria memberCriteria = memberExample.createCriteria();
        //memberCriteria.andEqualTo("name",name);
        //memberCriteria.andEqualTo("idCard",idCard);
        memberCriteria.andEqualTo("phoneNumber",phone);
        Member selectOneMember = memberDao.selectOneByExample(memberExample);
        log.info("[预约设置-add-当前用户在会员表中的数据] - selectOneMember: {}",selectOneMember);

        //判断用户当天是否对当前套餐进行预约
        if (selectOneMember!=null){
            Integer memberId = selectOneMember.getId();
            Order order = new Order();
            order.setMemberId(memberId);
            order.setOrderDate(date);
            order.setMemberId(memberId);
            int orderCount = orderDao.selectCount(order);
            if (orderCount>0){
                throw new CustomizeException(MessageConst.HAS_ORDERED);
            }
        }

        //组装t_order表
        Order order = new Order();
        order.setMemberId(selectOneMember.getId());
        order.setOrderDate(orderSubmitParam.getOrderDate());
        order.setSetmealId(orderSubmitParam.getSetMealId());
        order.setOrderType(Order.ORDERTYPE_WEIXIN);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        orderDao.insertSelective(order);

        InterProcessMutex lock = zkLockUtil.getZkLock();

        try {
            lock.acquire();

            //增加预约人数
            Example orderSettingExample = new Example(OrderSetting.class);
            Example.Criteria orderSettingCriteria = orderSettingExample.createCriteria();
            orderSettingCriteria.andEqualTo("orderDate",date);
            OrderSetting uploadOrderSetting = new OrderSetting();
            uploadOrderSetting.setReservations(reservations+1);
            orderSettingDao.updateByExampleSelective(uploadOrderSetting,orderSettingExample);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                lock.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        zkLockUtil.closeZkLock();

        return order.getId();
    }

    @Override
    public Order findById(Integer id) {
        return orderDao.selectByPrimaryKey(id);
    }

    @Override
    public Integer countBySetMealId(Integer id) {
        Order order = new Order();
        order.setSetmealId(id);
        int count = orderDao.selectCount(order);
        log.info("[订单-根据setMealId查询] - count: {}",count);
        return count;
    }


    @Override
    public List<Map<String, Object>> setMemberAge() {
        return null;
    }
}
